package com.zhuimeng.Application;

import com.alibaba.fastjson.JSONObject;
import com.zhuimeng.Application.entity.*;
import com.zhuimeng.Application.service.IHappyBeanHistoryService;
import com.zhuimeng.Application.service.IUserSelvice;
import com.zhuimeng.Application.utils.RoomCodeUtils;
import com.zhuimeng.Application.utils.RoomMangerUtils;
import com.zhuimeng.Application.utils.SessionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint("/gobank")
public class webcoketConfig {

    private static AtomicInteger number = new AtomicInteger(0);

    private static IHappyBeanHistoryService happyBeanHistoryService;

    private static IUserSelvice userSelvice;


    @Autowired
    public void setHappyBeanHistoryService(IHappyBeanHistoryService happyBeanHistoryService) {
        webcoketConfig.happyBeanHistoryService = happyBeanHistoryService;
    }

    @Autowired
    public void setUserSelvice(IUserSelvice userSelvice) {
        webcoketConfig.userSelvice = userSelvice;
    }


    @OnOpen
    public void onOpen(Session session) {
        System.out.println("链接服务器");
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("断开服务器");
        RoomMangerUtils.removeRoom(session);
    }

    @OnError
    public void onError(Session session, Throwable t) {
        t.printStackTrace();
        System.out.println("发生异常");
    }

    @OnMessage
    public void onMessage(String mes, Session session) {
        System.out.println("收到消息" + mes);

        JSONObject jsonObject = JSONObject.parseObject(mes);
        int mesType = jsonObject.getIntValue("msgType");
        if (mesType == 200) {
            createRoom(jsonObject, session);
        } else if (mesType == 201) {
            addRoom(jsonObject, session);
        } else if (mesType == 202) {
            dramGo(jsonObject, session);
        } else if (mesType == 203) {
            sendMessage(jsonObject, session);
        } else if (mesType == 204) {
            ReopenMessage(jsonObject, session);
        } else if (mesType == 205) {
            ReopenConfirm(jsonObject, session);
        } else if (mesType == 206) {
            RegretMessage(jsonObject, session);
        } else if (mesType == 207) {
            RegretConfirm(jsonObject, session);
        } else if (mesType == 208) {
            AdmitDefeat(jsonObject, session);
        } else if (mesType == 209) {
            addRoomSubscrribe(jsonObject, session);
        } else if (mesType == 210) {
            audioHandler(jsonObject, session);
        }
    }

    public void createRoom(JSONObject jsonObject, Session session) {
        String info = jsonObject.getString("info");
        String pass = jsonObject.getString("pass");
        Integer isSub = jsonObject.getIntValue("isSub");

        int Uid = jsonObject.getIntValue("uid");
        String nickname = jsonObject.getString("nickname");
        String header = jsonObject.getString("header");
        Integer beanNumber = jsonObject.getIntValue("beanNumber");

        user user = new user();
        user.setId(Uid);
        user.setNickname(nickname);
        user.setHeader(header);
        user.setHappyBean(beanNumber);

        Player player = new Player();
        player.setUser(user);
        player.setSession(session);

        Room room = new Room();
        room.setRoomId(number.incrementAndGet());
        room.setPlayer1(player);
        room.setStatus(0);
        room.setInfo(info);
        room.setPass(pass);
        room.setIsSubscrribe(isSub);

        RoomMangerUtils.putRoom(room.getRoomId(), room);
        RoomMangerUtils.putRoom(session, room);
    }

    public void addRoom(JSONObject jsonObject, Session session) {
        int rid = jsonObject.getIntValue("rid");
        String roomCode = jsonObject.getString("roomCode");

        int uid = jsonObject.getIntValue("uid");
        String nickname = jsonObject.getString("nickname");
        String header = jsonObject.getString("header");
        Integer beanNumber = jsonObject.getIntValue("beanNumber");


        user user = new user();
        user.setId(uid);
        user.setNickname(nickname);
        user.setHeader(header);
        user.setHappyBean(beanNumber);

        /**
         * 200 - 创建房间
         * 201 - 加入房间
         * 202 - 落子信息
         * 203 - 收到聊天消息
         * 204 - 重开
         * 205 - 重开确认
         * 206 - 悔棋
         * 207 - 悔棋确认
         * 208 - 认输
         * 209 - 加入观战
         * 210 - 语音消息
         *
         * 300 - 房间未找到
         * 301 - 人数已满
         * 302 - 密码错误
         * 303 - 房间验证码错误
         *
         * 400 - 有人加入房间
         * 401 - 加入房间成功
         * 402 - 对方落子
         * 403 - 我方落子
         * 404 - 对方聊天消息
         * 405 - 重开消息
         * 407 - 重开确认回调
         * 408 - 重开拒绝回调
         * 409 - 悔棋信息
         * 410 - 悔棋确认回调
         * 411 - 悔棋拒绝回调
         * 412 - 对方认输
         * 413 - 有人加入观战
         * 414 - 玩家落子
         * 415 - 玩家发送消息
         * 416 - 玩家重开
         * 417 - 玩家悔棋
         * 418 - 玩家认输
         * 419 - 音频消息
         * 420 - 玩家语音
         * 421 - 玩家加入房间
         */
        synchronized ((rid + "").intern()) {
            Room room = RoomMangerUtils.getRoom(rid);
            if (room == null) {
                SessionUtils.sendMes(session, message.returnmessage("300", "房间未找到"));
                return;
            }
            if (RoomCodeUtils.getCode(rid + "") == null || !RoomCodeUtils.getCode(rid + "").equals(roomCode)) {
                SessionUtils.sendMes(session, message.returnmessage("303", "房间验证码错误,请从主页进入房间"));
                return;
            } else {
                RoomCodeUtils.removeCode(rid + "");
            }

            Player player = new Player();
            player.setUser(user);
            player.setSession(session);

            RoomMangerUtils.putRoom(session, room);

            room.setPlayer2(player);
            room.setStatus(1);

            SessionUtils.sendMes(room.getPlayer1().getSession(), message.returnmessage("400", "有人加入房间").add("user", room.getPlayer2().getUser()));
            SessionUtils.sendMes(room.getPlayer2().getSession(), message.returnmessage("401", "加入房间成功").add("user", room.getPlayer1().getUser()));
            if(room.getSubscrribe().size()!=0) {
                for (Player player1 : room.getSubscrribe()) {
                    SessionUtils.sendMes(room.getPlayer1().getSession(), message.returnmessage("413", "有人加入观战").add("code", "1").add("user", player1.getUser()));
                    SessionUtils.sendMes(room.getPlayer2().getSession(), message.returnmessage("413", "有人加入观战").add("code", "1").add("user", player1.getUser()));
                    SessionUtils.sendMes(player1.getSession(), message.returnmessage("421", "有人加入房间").add("user", room.getPlayer2().getUser()));
                }
            }
        }
    }


    public void dramGo(JSONObject jsonObject, Session session) {
        int x = jsonObject.getIntValue("x");
        int y = jsonObject.getIntValue("y");
        int goColor = jsonObject.getIntValue("goColor");//0 - 黑 1 - 白


        Room room = RoomMangerUtils.getRoom(session);
        GoBank goBank = room.getGoBank();
        boolean isOk = goBank.go(x, y, goColor);
        if (isOk) {
            boolean isWin = goBank.isWin(x, y, goColor);

            if (isWin) {
                Player player = room.getPlayer(session);
                userSelvice.updataHappyBean(player.getUser().getId(), 1000);
                HappyBeanHistory happyBeanHistory = new HappyBeanHistory();
                happyBeanHistory.setuId(player.getUser().getId());
                happyBeanHistory.setType(0);
                happyBeanHistory.setBeanNumber(1000);
                happyBeanHistory.setCreateTime(new Date());
                happyBeanHistory.setSource(1);
                happyBeanHistoryService.insertHistory(happyBeanHistory);

                Player otherPlayer = room.getOtherPlayer(session);
                userSelvice.updataHappyBean(otherPlayer.getUser().getId(), -1000);
                HappyBeanHistory otherHappyBeanHistory = new HappyBeanHistory();
                otherHappyBeanHistory.setuId(otherPlayer.getUser().getId());
                otherHappyBeanHistory.setType(1);
                otherHappyBeanHistory.setBeanNumber(1000);
                otherHappyBeanHistory.setCreateTime(new Date());
                otherHappyBeanHistory.setSource(1);
                happyBeanHistoryService.insertHistory(otherHappyBeanHistory);
            }
            Session otherSession = room.getOtherPlayer(session).getSession();
            SessionUtils.sendMes(otherSession, message.returnmessage("402", "对方落子").add("goBand", goPull.add(x, y, goColor)).add("isWin", isWin));
            SessionUtils.sendMes(session, message.returnmessage("403", "我方落子").add("goBand", goPull.add(x, y, goColor)).add("isWin", isWin));

            for (Player player : room.getSubscrribe()) {
                if (player.getSession().isOpen()) {
                    SessionUtils.sendMes(player.getSession(), message.returnmessage("414", "玩家落子").add("user", (room.getPlayer1().getSession() == session ? "0" : "1")).add("goBand", goPull.add(x, y, goColor)).add("isWin", isWin));
                }
            }
        }
    }


    public void sendMessage(JSONObject jsonObject, Session session) {
        String mes = jsonObject.getString("mes");
        Room room = RoomMangerUtils.getRoom(session);
        Player player = room.getOtherPlayer(session);
        if (player != null) {
            Session otherSession = player.getSession();
            SessionUtils.sendMes(otherSession, message.returnmessage("404", "对方发送消息").add("mes", mes));
        }
        for (Player player1 : room.getSubscrribe()) {
            if (player1.getSession().isOpen()) {
                SessionUtils.sendMes(player1.getSession(), message.returnmessage("415", "对方发送消息").add("userName", room.getPlayer(session).getUser().getNickname()).add("mes", mes));
            }
        }
    }

    public void RegretMessage(JSONObject jsonObject, Session session) {
        Room room = RoomMangerUtils.getRoom(session);
        if (room.getPlayerRegret() != -2) {
            return;
        }
        room.setPlayerRegret(1);
        SessionUtils.sendMes(session, message.returnmessage("409", "悔棋信息").add("code", "0"));
        SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("409", "悔棋信息").add("code", "1"));
    }

    public void RegretConfirm(JSONObject jsonObject, Session session) {
        int isMe = jsonObject.getIntValue("isMe");
        int isConfirm = jsonObject.getIntValue("isConfirm");
        Room room = RoomMangerUtils.getRoom(session);
        if (room.getPlayerRegret() != 1) {
            return;
        }
        if (isConfirm == 0) {
            //同意悔棋
            List Step;
            if (isMe == 0) {
                Step = room.getGoBank().getStep(1);
            } else {
                Step = room.getGoBank().getStep(2);
            }
            System.out.println(Step);
            SessionUtils.sendMes(session, message.returnmessage("410", "我确认你悔棋").add("code", "0").add("isMe", "0").add("step", Step));
            SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("410", "对方确认我悔棋").add("code", "1").add("isMe", "1").add("step", Step));

            for (Player player : room.getSubscrribe()) {
                if (player.getSession().isOpen()) {
                    SessionUtils.sendMes(player.getSession(), message.returnmessage("417", "玩家悔棋").add("step", Step));
                }
            }
        } else {
            //不同意悔棋
            SessionUtils.sendMes(session, message.returnmessage("411", "我拒绝你悔棋").add("code", "0"));
            SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("411", "对方拒绝我悔棋").add("code", "1"));
        }
        room.setPlayerRegret(-2);
    }

    public void ReopenMessage(JSONObject jsonObject, Session session) {
        Room room = RoomMangerUtils.getRoom(session);
        if (room.getPlayerReopen() != -2) {
            return;
        }
        SessionUtils.sendMes(session, message.returnmessage("405", "重开信息").add("code", "0"));
        SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("405", "重开信息").add("code", "1"));
        room.setPlayerReopen(1);
    }

    public void ReopenConfirm(JSONObject jsonObject, Session session) {
        int isConfirm = jsonObject.getIntValue("isConfirm");
        Room room = RoomMangerUtils.getRoom(session);
        if (room.getPlayerReopen() != 1) {
            return;
        }
        if (isConfirm == 0) {
            //同意重开
            room.getGoBank().clearBand();
            room.setPlayerRegret(-2);
            room.setPlayerReopen(-2);
            SessionUtils.sendMes(session, message.returnmessage("407", "我确认你重开").add("code", "0"));
            SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("407", "对方确认我重开").add("code", "1"));

            for (Player player : room.getSubscrribe()) {
                if (player.getSession().isOpen()) {
                    SessionUtils.sendMes(player.getSession(), message.returnmessage("416", "玩家重开"));
                }
            }
        } else {
            //不同意重开
            SessionUtils.sendMes(session, message.returnmessage("408", "我拒绝你悔棋").add("code", "0"));
            SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("408", "对方拒绝我悔棋").add("code", "1"));
        }
        room.setPlayerReopen(-2);

    }

    public void AdmitDefeat(JSONObject jsonObject, Session session) {
        Room room = RoomMangerUtils.getRoom(session);

        Player player = room.getPlayer(session);
        userSelvice.updataHappyBean(player.getUser().getId(), -1000);
        HappyBeanHistory happyBeanHistory = new HappyBeanHistory();
        happyBeanHistory.setuId(player.getUser().getId());
        happyBeanHistory.setType(1);
        happyBeanHistory.setBeanNumber(1000);
        happyBeanHistory.setCreateTime(new Date());
        happyBeanHistory.setSource(1);
        happyBeanHistoryService.insertHistory(happyBeanHistory);

        Player otherPlayer = room.getOtherPlayer(session);
        userSelvice.updataHappyBean(otherPlayer.getUser().getId(), 1000);
        HappyBeanHistory otherHappyBeanHistory = new HappyBeanHistory();
        otherHappyBeanHistory.setuId(otherPlayer.getUser().getId());
        otherHappyBeanHistory.setType(0);
        otherHappyBeanHistory.setBeanNumber(1000);
        otherHappyBeanHistory.setCreateTime(new Date());
        otherHappyBeanHistory.setSource(1);
        happyBeanHistoryService.insertHistory(otherHappyBeanHistory);

        SessionUtils.sendMes(room.getOtherPlayer(session).getSession(), message.returnmessage("412", "对方认输").add("code", "0"));
        SessionUtils.sendMes(session, message.returnmessage("412", "我方认输").add("code", "1"));

        for (Player player1 : room.getSubscrribe()) {
            if (player1.getSession().isOpen()) {
                SessionUtils.sendMes(player1.getSession(), message.returnmessage("418", "玩家认输").add("user", (room.getPlayer1().getSession() == session ? 0 : 1)));
            }
        }
    }

    public void addRoomSubscrribe(JSONObject jsonObject, Session session) {
        int rid = jsonObject.getIntValue("rid");

        int uid = jsonObject.getIntValue("uid");
        String nickname = jsonObject.getString("nickname");
        String header = jsonObject.getString("header");


        user user = new user();
        user.setId(uid);
        user.setNickname(nickname);
        user.setHeader(header);

        Player player = new Player();
        player.setSession(session);
        player.setUser(user);

        Room room = RoomMangerUtils.getRoom(rid);
        room.put2Subscrribe(player);

        int isReady;
        if(room.getPlayer2()==null){
            isReady=0;
            SessionUtils.sendMes(session, message.returnmessage("413", "加入观战成功").add("code", "0").add("player1", room.getPlayer1().getUser()).add("isReady",isReady));
        }else {
            isReady=1;
            List step = room.getGoBank().getStep(0);
            SessionUtils.sendMes(session, message.returnmessage("413", "加入观战成功").add("code", "0").add("player1", room.getPlayer1().getUser()).add("player2", room.getPlayer2().getUser()).add("step", step).add("isReady",isReady));
            SessionUtils.sendMes(room.getPlayer1().getSession(), message.returnmessage("413", "有人加入观战").add("code", "1").add("user", user));
            SessionUtils.sendMes(room.getPlayer2().getSession(), message.returnmessage("413", "有人加入观战").add("code", "1").add("user", user));
        }
    }

    public void audioHandler(JSONObject jsonObject, Session session) {
        //获得音频聊天文件
        String audio = jsonObject.getString("audio");

        //获取对手的session
        Room room = RoomMangerUtils.getRoom(session);
        Player otherPlayer = room.getOtherPlayer(session);
        //判断对手是否存在
        if (otherPlayer != null) {
            //将聊天信息 发送给对方
            Map result = new HashMap();
            result.put("msgType", 405);
            result.put("audio", audio);//对方发送的聊天内容
            SessionUtils.sendMes(otherPlayer.getSession(), message.returnmessage("419", "语音消息").add("audio", audio));
            for (Player player1 : room.getSubscrribe()) {
                if (player1.getSession().isOpen()) {
                    SessionUtils.sendMes(player1.getSession(), message.returnmessage("420", "玩家语音消息").add("audio",audio).add("user", room.getPlayer(session).getUser()));
                }
            }
        }
    }

}
